package com.jacob.androidstudy.androidnote.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;


/**
 * Service：
 * 1 Service是一种重要的Android程序组件，提供后台长时间操作，没有用户界面。
 * 2 其他程序组件可以启动Service，即使用户切换到其他程序，Service仍会持续在后台运行。
 * 3 此外，组件可以绑定1个Service，甚至可以执行进程间的通信。
 * 4 例如：Service可以在后台处理网络操作、播放音乐、执行文件读写、和ContentProvider相互作用。
 * 5 Service并不会创建自己的进程或线程，而是运行在程序的主线程中，除非自己写多线程代码。所以，若Service执行的操作耗时较长，应该新建一个线程执行代码。
 * 6 系统只有在需要释放内存给得到用户焦点Activity时，才会杀掉Service。如果Service和得到用户焦点的Activity绑定了，就不太可能会被杀死；如果Service在前台运行，基本上就从来不会被系统杀死。
 * 
 * 
 * Service的分类：
 * 1 Started Service
 *  1.1 通过在其他组件中，调用startService()来启动。
 *  1.2 启动后，运行在后台，即使启动Started Service的组件对象销毁了，Started Service也不会停止。
 *  1.3 通常只启动，不返回值。
 *  1.4 通常用于上传和下载业务。
 * 
 * 2 Bound Service
 *  2.1 BoundService是CS结构的Service。BoundService允许程序组件（例如Activity）和自己绑定，接收请求并返回结果，甚至进行进程间通信。
 *  2.2 BoundService不会无限期的在后台运行。只要所有绑定的组件消亡，BoundService就消亡。（除非BoundService也是StartedService，并通过startService()启动了。）
 *  2.3 只有Activity、Service和ContendProvider可以绑定BoundService，BroadcastReceiver不可以。
 *  2.4 在客户端声明周期中，应该成对使用bindService()和unbindService()。
 *   2.4.1 如果只需要在Activity可见时，和BoundService互动。应该在Activity的onStart()方法中bindService()，在onStop()方法中unbindService()。
 *   2.4.2 如果想让Activity在后台停止后，依然接收响应。应该在Activity的onCreate()方法中bindService()，在onDestroy()方法中unbindService()。注意：此时Activity只要运行（即使在后台运行），就需要一直使用BoundService。若BoundService在另一个进程中，就会造成这个进程占用了更多资源，系统有可能会因此杀掉它。
 *   2.4.3 一般不应该在Activity的onResume()和onPause()中绑定和取消绑定BoundService，因为这些回调方法，在每次Activity状态改变时都会被调用，而这些生命周期的状态改变应该尽量的减少。另外，若程序中有多个Activity绑定到同一个BoundService，在Activity状态改变时，若一个Activity暂停，而另一个Activity还未恢复，就会造成BoundService被销毁然后重新实例化。
 *  2.5 调用远程方法时，不要忘记捕捉DeadObjectException异常。当连接断掉时，远程方法会抛出此异常。
 * 
 *
 * Service的生命周期：
 * 1 StartedService
 *  1.1 首先，StartedService处于消亡状态。
 *  1.2 在其他组件中调用startService()，系统调用onCreate()、onStartCommand()。StartedService变为运行状态。
 *  1.3 在其他组件中再一次调用startService()，系统调用onStartCommand()。StartedService保持运行状态。
 *  1.4 在其他组件中调用stopService()、或者在StartedService中调用stopSelf(startId)，系统调用onDestroy()。StartedService变回消亡状态。
 * 
 * 2 BoundService
 *  2.1 首先，BoundService处于消亡状态。
 *  2.2 在组件A中调用bindService()，系统调用onCreate()、onBind()。BoundService变为运行状态。
 *  2.3 在组件B中再一次调用bindService()，系统直接将IBinder对象返回给调用者。BoundService保持运行状态。
 *  2.4 在组件A中调用unbindService()，系统取消组件A和BoundService的绑定关系。BoundService保持运行状态。
 *  2.5 在组件B中调用unbindService()，系统取消组件A和BoundService的绑定关系，并调用onUnbind()、onDestroy()。BoundService变回消亡状态。
 *  
 * 3 StartedService + BoundService
 *  3.1 无论startService()和bindService()都会实例化Service。
 *  3.2 系统只在实例化Service的时候才会调用onCreate()。
 *  3.3 调用bindService()后，是无法用stopService()或者stopSelf(startId)停止Service的。
 *  3.4 看看官网的Service生命周期图。
 * 
 * 
 * 
 */

/**
 * Started Service的生成步骤：
 * 1 定义Started Service，并继承于android.app.Service。
 * 2 在AndroidManifest.xml中注册定义好的Started Service。
 * 3 在Started Service中编写业务方法。
 * 4 在onStartCommand()方法中，调用需要执行的代码和业务方法。
 * 5 在Activity中调用startService(new Intent(this,Service.class))，Started Service就会启动，直到被手工停止。
 * 6 Started Service启动时，系统会依次调用onCreate()方法、onStartCommand()方法。
 * 7 停止Service，有两种方法：
 *  7.1 在Activity中调用stopService(new Intent(this,Service.class))。
 *  7.2 在Started Service中，调用stopSelf(startId)，停止自己。
 * 
 * 
 */

/**
 * Bound Service的生成步骤
 * 1 定义Bound Service，并继承于android.app.Service。
 * 2 在AndroidManifest.xml中注册定义好的Bound Service。
 * 3 提供IBinder接口
 *  3.1 继承android.os.Binder类。用于不涉及跨线程的本地Service。
 *  3.2 使用android.os.Messenger类。用于跨进程通信的远程Service。
 *  3.3 使用AIDL。因为设计多线程处理，大多数程序不需要使用这种方式。
 * 3 实现onBind()方法，此方法返回1个IBinder对象。
 * 4 在客户端定义三个属性，分别存放IBinder对象，Bound Service对象，绑定标志位。
 * 5 客户端创建一个ServiceConnection的实现类，覆盖onServiceConnected()和onServiceDisconnected()方法。系统会调用onServiceConnected()方法将IBinder对象传过去，这里应该给3个属性赋值。和BoundService的连接意外断开时，系统调用onServiceDisconnected()方法，正常unbound时并不会调用。
 * 6.客户端生成Intent对象。
 * 7.客户端调用bindService()，传入Intent对象、ServiceConnection对象、标志位，绑定过程是异步的，bindService()被客户端调用后立即就会返回。
 * 8.需要取消绑定时，在客户端调用unbindService()。虽然系统会在客户端销毁时，自动取消和BoundService的绑定，但是应该在工作完成后、或者客户端被停止时手工取消和BoundService的绑定。
 * 
 */

public class Android四大组件之Service extends Service{

	
	/**
	 * Service第一次被创建时，系统会先调用本方法。（在调用onStartCommand()方法和onBind()方法前）
	 * 如果Service已经运行了，则系统不会再调用本方法。
	 * 
	 */
	@Override
	public void onCreate() {
		super.onCreate();
	}
	
	/**
	 * 当其他组件（例如Activity）调用startService()，请求启动Service时，系统会调用本方法。
	 * 一旦本方法被执行，Service就启动了，并运行在后台。
	 * 如果你想写一个Bound Service，不需要覆盖这个方法。一旦覆盖了这个方法，就需要你手工停止Service。
	 * 本方法必须返回整数值，这个值表示Service被系统杀掉后，在恢复运行时，应该以何种方式恢复。这个值只能是下面几个：
	 * Service.START_STICKY - 如果Service在onStartCommand()方法返回后被系统杀掉，不要重新创建Service，除非有等待发送的Intent对象。这个选项可以避免在不必要的情况下运行 Service。
	 * Service.START_NOT_STICKY - 如果Service在onStartCommand()方法返回后被系统杀掉，重新创建Service，并调用onStartCommand()方法，但是不会重新传入上一个Intent对象。若有等待发送的Intent对象，系统就传这个对象；若没有，则传null。这个选项适合多媒体播放器类的Service，这类Service不立即执行命令，只是一直运行着等待用户命令。
	 * Service.START_REDELIVER_INTENT - 如果Service在onStartCommand()方法返回后被系统杀掉，重新创建Service，并调用onStartCommand()方法，传入上一个 Intent对象。其他等待发送的Intent对象会轮流发送。这个选项 适合需要积极执行某种工作的、需要立即被恢复的Service。例如：下载文件的Service。 
	 * 
	 * 第二个参数flags
	 * 如果等于0，表示Service是正常启动的；
	 * 如果等于Service.START_FLAG_RETRY，表示Service是被杀死后重新启动的；
	 * 如果等于Service.START_FLAG_REDELIVERY，表示Service是被杀死后重新启动的，并且Intent对象也是重新传入的。
	 * 
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		this.stopSelf(startId);
		return super.onStartCommand(intent, flags, startId);
		
		
	}
	
	
	
	/**
	 * 因为IBinder对象依赖BoundService对象，所以这里使用内部类。
	 * IBinder为客户端提供getService()，用来传递当前Service的对象。
	 * 客户端可以用IBinder对象调用其中的public方法，也可以用IBinder.getService()调用Service中的public方法。
	 * 
	 */
	public class LocalBinder extends Binder {
		
		Android四大组件之Service getService() {
			return Android四大组件之Service.this;
		}
		
		public void publicMethod() {
			
		}
		
	}
	
	/**
	 * 将IBinder对象定义为BoundService的属性，可以保证一个BoundService对应一个IBinder对象。
	 */
	private IBinder mIBinder = new LocalBinder();
	
	/**
	 * 当其他组件第一次调用bindService()方法绑定Service时，系统调用本方法。以后再有组件调用bindService()方法，系统不再调用本方法，直接返回IBinder对象。
	 * 覆盖本方法时，必须提供一个供clients用来和Service通信的接口对象（IBinder对象）。
	 * 本方法必须被覆盖，但是若不希望Service能被绑定，应该返回null。
	 * 
	 */
	@Override
	public IBinder onBind(Intent intent) {
		return mIBinder;
	}
	
	@Override
	public boolean onUnbind(Intent intent) {
		return super.onUnbind(intent);
	}

	/**
	 * Service被停止时，系统会调用本方法。
	 * 你应该覆盖本方法，以清理资源。（thread、registered listener、receiver等）
	 * 
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
	}
	
	
	
	
	
}
